package com.aplikata.evok.ui;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.model.ListDataModel;

import net.sf.jasperreports.engine.JasperPrint;

import org.apache.myfaces.custom.fileupload.UploadedFile;
import org.hibernate.Hibernate;
import org.primefaces.event.RowEditEvent;
import org.primefaces.event.SelectEvent;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SelectableDataModel;
import org.primefaces.model.SortOrder;
import org.primefaces.model.TreeNode;
import org.springframework.jdbc.core.JdbcTemplate;

import com.aplikata.bo.Employee;
import com.aplikata.bo.Node;
import com.aplikata.constants.ConstantsMsg;
import com.aplikata.evok.bo.DoctorSchedule;
import com.aplikata.evok.bo.DomainPatient;
import com.aplikata.evok.bo.EvokService;
import com.aplikata.evok.bo.Patient;
import com.aplikata.evok.bo.PatientTherapy;
import com.aplikata.evok.bo.PatientTherapyAttachment;
import com.aplikata.evok.bo.PatientTherapyComment;
import com.aplikata.evok.bo.PatientTherapyNode;
import com.aplikata.evok.bo.Therapy;
import com.aplikata.evok.bo.TherapyService;
import com.aplikata.evok.constants.EvokConstants;
import com.aplikata.evok.datamodel.DomainPatientDataModel;
import com.aplikata.evok.datamodel.TherapyAttachmentDataModel;
import com.aplikata.evok.datamodel.TherapyServiceDataModel;
import com.aplikata.evok.email.EvokEmailUtil;
import com.aplikata.util.FacesUtil;
import com.aplikata.util.ReportUtil;
import com.aplikata.util.StringUtil;
import com.aplikata.util.YunDateUtil;

/**
 * @ClassName: EvokPatientTherapyBean
 * @Description: TODO
 * @author Huyun
 * @date May 27, 2012 10:21:41 PM
 */
@ManagedBean(name = "evokPatientTherapyBean")
@ViewScoped
public class EvokPatientTherapyBean extends EvokPatientTherapyAbstractBean {
	private static final long serialVersionUID = 1L;

	@ManagedProperty(value = "#{jdbcTemplate}")
	private JdbcTemplate jdbcTemplate;

	protected int leftTabIndex;

	private Long roleId;

	private String qyPatientName;
	private DomainPatient domainPatient;

	private DomainPatientDataModel domainPatientModel;
	private LazyDataModel<Object[]> patientTherapyModel;

	private TreeNode[] selectedCategoryNodes;

	// for dynamic category tab
	private List<PatientTherapyNode> pnList;

	// for service tab
	private TherapyService therapyService;
	private Long serviceId;
	private String unit;
	private String currency;
	private List<EvokService> serviceList;
	private TherapyServiceDataModel tsModel;
	private String priceTotal;

	// for attachement tab
	private UploadedFile therapyAtt;
	private PatientTherapyAttachment att;
	private TherapyAttachmentDataModel attmodel;

	// for reservation
	private DoctorSchedule schedule;

	@SuppressWarnings({ "unchecked" })
	@PostConstruct
	public void init() {
		super.init();
		roleId = FacesUtil.getUserFromSession().getRole().getId();
		therapyService = new TherapyService();
		att = new PatientTherapyAttachment();

		domainPatient = (DomainPatient) FacesContext.getCurrentInstance().getExternalContext().getFlash()
				.get(EvokConstants.FLASH_SCHEDULE_DOMAIN_PATIENT);
		schedule = (DoctorSchedule) FacesContext.getCurrentInstance().getExternalContext().getFlash()
				.get(EvokConstants.FLASH_SCHEDULE);
		patientTherapy = (PatientTherapy) FacesContext.getCurrentInstance().getExternalContext().getFlash()
				.get(EvokConstants.FLASH_PATIENT_THERAPY);

		if (patientTherapy != null) {
			leftTabIndex = 1;
			domainPatientModel = new DomainPatientDataModel(evokTherapyService, new ArrayList<DomainPatient>(
					Arrays.asList(domainPatient)));
			therapyReservationList = (List<DoctorSchedule>) evokTherapyService.findByNamedQuery(
					DoctorSchedule.QY_FIND_PATIENT_THERAPY, new Object[] { patientTherapy.getId() });
		}

		if (domainPatient != null && schedule != null) {
			Patient patient = domainPatient.getPatient();
			qyPatientName = patient.getSurname() + " " + patient.getName() + " "
					+ YunDateUtil.formatDate(patient.getBirthday(), "dd/MM/yyyy") + " " + domainPatient.getId();
			selectPatientName(qyPatientName);
		}

		if (schedule != null && schedule.getPatientTherapy() != null) {
			patientTherapy = (PatientTherapy) evokTherapyService.get(PatientTherapy.class, schedule.getPatientTherapy()
					.getId());
			selectPatientTherapy(patientTherapy);
		} else if (schedule != null && schedule.getPatientTherapy() == null) {
			therapyReservationList = new ArrayList<DoctorSchedule>();
			therapyReservationList.add(schedule);
		}

		if (patientTherapy == null) {
			patientTherapy = new PatientTherapy(FacesUtil.getUserFromSession());
		}
		// FacesUtil.setManagedBeanInSession(EvokConstants.SESSION_SCHEDULE_PATIENT,
		// null);
		// FacesUtil.setManagedBeanInSession(EvokConstants.SESSION_SCHEDULE,null);
	}

	@SuppressWarnings("unchecked")
	public List<String> completeQueryName(String query) {
		return (List<String>) evokTherapyService.findByNamedQuery(DomainPatient.QY_FIND_NAME,
				new Object[] { this.getQyDomainId(), query + "%" });
	}

	public void selectPatientName(SelectEvent event) {
		domainPatient = null;
		selectPatientName((String) event.getObject());
	}

	private void selectPatientName(String patientName) {
		qyPatientName = patientName;
		String idString = qyPatientName.substring(qyPatientName.lastIndexOf(" "), qyPatientName.length());
		Long id = Long.parseLong(idString.trim());
		List<DomainPatient> list = new ArrayList<DomainPatient>();
		list.add((DomainPatient) evokTherapyService.get(DomainPatient.class, id));

		if (domainPatientModel == null) {
			domainPatientModel = new DomainPatientDataModel(evokTherapyService, list);
		} else {
			domainPatientModel.setWrappedData(list);
		}

		domainPatient = list.get(0);
		selectDomainPatient(domainPatient);
		FacesUtil.unselectTableRows("wdgPatientList");
		FacesUtil.unselectTableRows("wdgTherapyList");
	}

	public void rowEditReservation(RowEditEvent event) {
		int index = therapyReservationList.indexOf(event.getObject());
		schedule = (DoctorSchedule) event.getObject();

		try {
			schedule.setDomainPatient(domainPatient);
			schedule.setPatientTherapy(patientTherapy);
			schedule = evokTherapyService.updatePatientTherapySchedule(patientTherapy, schedule, selectedCategoryNodes,
					pnList);

			// send email
			if(schedule.getStatus() != null && EvokConstants.DOC_RESERVATION_STATUS_CANCEL == schedule.getStatus().intValue())
				EvokEmailUtil.sendReservationEmail(domainPatient.getPatient().getId(), schedule,schedule.getStatus());

			patientTherapy = schedule.getPatientTherapy();
			patientTherapyModel = null;
			patientTherapyModel = this.getPatientTherapyModel();
			therapyReservationList.remove(index);
			therapyReservationList.add(index, schedule);
			FacesUtil.addInfoMessage(ConstantsMsg.INFO_SUCCESS, new Object[] { "" });
		} catch (Exception e) {
			FacesUtil.addActionListenerException(e, log);
		}
	}

	public void addReservation() {
		schedule = new DoctorSchedule();
		if (therapyReservationList == null)
			therapyReservationList = new ArrayList<DoctorSchedule>();

		therapyReservationList.add(0, schedule);
	}

	public void deleteDoctorReservation() {
		try {
			if (schedule == null || FacesUtil.isKeyNull(schedule.getId())) {
				if (therapyReservationList.contains(schedule))
					therapyReservationList.remove(schedule);
				return;
			}
			evokTherapyService.deleteByKey(DoctorSchedule.class, schedule.getId());
			EvokEmailUtil.sendReservationEmail(domainPatient.getPatient().getId(), schedule, EvokConstants.DOC_RESERVATION_STATUS_CANCEL);
			therapyReservationList.remove(schedule);
			FacesUtil.addInfoMessage(ConstantsMsg.INFO_SUCCESS, new Object[] { "" });
		} catch (Exception e) {
			FacesUtil.addActionListenerException(e, log);
		}
	}

	public void resetQuery() {
		FacesUtil.resetInput("mainform:tabviewTherapy");
		FacesUtil.resetInput("mainform:patientname");
		tabIndex = 0;
		qyPatientName = null;
		domainPatient = new DomainPatient();
		patientTherapy = new PatientTherapy(getSessionUser());
		domainPatientModel = null;
		patientTherapyModel = null;
		therapyTree = null;
		therapyTree = this.getTherapyTree();
		selectedCategoryNodes = null;
		priceTotal = null;
		unit = null;
		serviceId = null;
		therapyReservationList = null;
		FacesUtil.unselectTableRows("wdgPatientList");
		FacesUtil.unselectTableRows("wdgTherapyList");
	}

	public void queryPatient() {
		domainPatient = domainPatientModel.getRowData();
		FacesContext.getCurrentInstance().getExternalContext().getFlash().put("queryDomainPatient", domainPatient);
	}

	public void addTherapy() {
		resetFlash();

		domainPatient = domainPatientModel.getRowData();
		if (domainPatient == null || FacesUtil.isKeyNull(domainPatient.getId())) {
			return;
		}

		selectDomainPatient(domainPatient);
		FacesUtil.unselectTableRows("wdgPatientList");
	}

	private void selectDomainPatient(DomainPatient dp) {
		if (dp == null || FacesUtil.isKeyNull(dp.getId()))
			return;

		domainPatient = dp;
		patientTherapyModel = null;
		patientTherapyModel = this.getPatientTherapyModel();

		patientTherapy = new PatientTherapy(domainPatient, FacesUtil.getUserFromSession());
		therapyTree = null;
		therapyTree = this.getTherapyTree();
		selectedCategoryNodes = null;

		pnList = null;
		tsModel = null;
		resetService();
		attmodel = null;
		commentList = null;
		tabIndex = 0;

		FacesUtil.unselectTableRows("wdgTherapyList");
	}

	private String getTherapySql(DomainPatient dp, Long patientTherapyId) {
		String sql = "SELECT {e.*}, group_concat(t.name order by t.parent_id, t.sort separator '<br/>') as category "
				+ " FROM evk_patient_therapy e, evk_patient_therapy_category c, evk_therapy t "
				+ " WHERE e.id=c.patient_therapy_id and t.id = c.therapy_id " + " AND creator = "
				+ this.getSessionUser().getId();

		if (dp != null && !FacesUtil.isKeyNull(dp.getId())) {
			sql += " AND e.domain_patient_id= " + dp.getId();
		}
		if (!FacesUtil.isKeyNull(patientTherapyId)) {
			sql += " AND e.id = " + patientTherapyId;
		}

		sql += " GROUP BY e.id order by e.start_date desc";
		return sql;
	}

	@SuppressWarnings({})
	public void selectDomainPatient(SelectEvent event) {
		resetFlash();
		domainPatient = (DomainPatient) event.getObject();
		selectDomainPatient(domainPatient);
	}

	@SuppressWarnings("unchecked")
	private void selectPatientTherapy(PatientTherapy pt) {
		patientTherapy = pt;
		addTherapyToFlash();

		therapyTree = evokTherapyService.getTherapyTreeForDoctor(roleId, patientTherapy);

		pnList = evokTherapyService.getPatientTherapyNodeList(roleId, patientTherapy);

		resestService();
		comment = new PatientTherapyComment();
		commentList = null;
		commentList = this.getCommentList();

		attmodel = null;
		attmodel = this.getAttmodel();

		priceTotal = null;
		priceTotal = this.getPriceTotal();
		FacesUtil.unselectTableRows("wdgAtt");

		therapyReservationList = (List<DoctorSchedule>) evokTherapyService.findByNamedQuery(
				DoctorSchedule.QY_FIND_PATIENT_THERAPY, new Object[] { patientTherapy.getId() });
	}

	public void selectPatientTherapy(SelectEvent event) {
		resetFlash();
		patientTherapy = (PatientTherapy) ((Object[]) event.getObject())[0];
		selectPatientTherapy(patientTherapy);
	}

	@SuppressWarnings("unchecked")
	public void selectPatientReservation(SelectEvent event) {
		schedule = (DoctorSchedule) event.getObject();
		domainPatient = schedule.getDomainPatient();
		patientTherapy = new PatientTherapy(domainPatient, FacesUtil.getUserFromSession());
		therapyTree = null;
		therapyTree = this.getTherapyTree();
		selectedCategoryNodes = null;
		tabIndex = 0;
		// selectPatient(patient);

		if (schedule.getPatientTherapy() != null) {
			patientTherapy = (PatientTherapy) evokTherapyService.get(PatientTherapy.class, schedule.getPatientTherapy()
					.getId());
			selectPatientTherapy(patientTherapy);
			therapyReservationList = (List<DoctorSchedule>) evokTherapyService.findByNamedQuery(
					DoctorSchedule.QY_FIND_PATIENT_THERAPY, new Object[] { patientTherapy.getId() });
		} else {
			therapyReservationList = new ArrayList<DoctorSchedule>();
			therapyReservationList.add(schedule);
		}
	}

	@SuppressWarnings("unchecked")
	public void submit() {
		if (patientTherapy == null)
			return;

		if (domainPatient == null || FacesUtil.isKeyNull(domainPatient.getId())) {
			FacesUtil.addErrorMessage(PatientTherapy.MSG_PATIENT_NULL);
			return;
		}

		if (selectedCategoryNodes == null || selectedCategoryNodes.length == 0) {
			FacesUtil.addErrorMessage(ConstantsMsg.MSG_REQUIRE,
					new Object[] { FacesUtil.getMessage(Therapy.LB_CATEGORY) });
			return;
		}

		try {
			patientTherapy.setDomainPatient(domainPatient);
			patientTherapy = (PatientTherapy) evokTherapyService.updatePatientTherapy(patientTherapy, schedule,
					selectedCategoryNodes, pnList);
			therapyReservationList = (List<DoctorSchedule>) evokTherapyService.findByNamedQuery(
					DoctorSchedule.QY_FIND_PATIENT_THERAPY, new Object[] { patientTherapy.getId() });
			addTherapyToFlash();

			// selectPatient(patient);
			
			
			FacesUtil.addInfoMessage(ConstantsMsg.INFO_SUCCESS, new Object[] { "" });
			// FacesUtil.unselectTableRows("wdgPatientList");
			// FacesUtil.unselectTableRows("wdgTherapyList");
			// FacesUtil.unselectTableRows("wdgResList");
		} catch (Exception e) {
			FacesUtil.addActionListenerException(e, log);
		}
	}

	public void delete() {
		if (patientTherapy == null || FacesUtil.isKeyNull(patientTherapy.getId()))
			return;

		try {
			evokTherapyService.deleteByKey(PatientTherapy.class, patientTherapy.getId());
			tabIndex = 0;
			patientTherapy = new PatientTherapy(getSessionUser());
			patientTherapyModel = null;
			therapyTree = null;
			therapyTree = this.getTherapyTree();
			selectedCategoryNodes = null;
			priceTotal = null;
			unit = null;
			serviceId = null;
			therapyReservationList = null;
			FacesUtil.unselectTableRows("wdgPatientList");
			FacesUtil.unselectTableRows("wdgTherapyList");
			FacesUtil.addInfoMessage(ConstantsMsg.INFO_SUCCESS, new Object[] { "" });
		} catch (Exception e) {
			FacesUtil.addActionListenerException(e, log);
		}
	}

	public void serviceChange() {
		if (serviceId == null) {
			therapyService = new TherapyService();
		} else {
			EvokService service = (EvokService) evokTherapyService.get(EvokService.class, serviceId);
			if (service != null) {
				therapyService.setService(service);
				therapyService.setPriceUnit(service.getPrice());
				this.setUnit(service.getUnit().toString());
				currency = service.getCurrency().toString();
				unit = service.getUnit().toString();

				therapyService.setAmount(null);
				therapyService.setPriceTotal(null);
			}
		}
	}

	private void resestService() {
		FacesUtil.unselectTableRows("wdgServiceList");
		therapyService = new TherapyService();
		serviceId = null;
		tsModel = null;
		tsModel = this.getTsModel();
	}

	public void submitService() {
		try {
			if (patientTherapy == null || FacesUtil.isKeyNull(patientTherapy.getId()) || therapyService == null)
				return;

			if (therapyService.getService() == null) {
				FacesUtil.addErrorMessage(ConstantsMsg.MSG_REQUIRE,
						new Object[] { FacesUtil.getMessage("default_name") });
				return;
			}

			if (therapyService.getAmount() == null
					|| (therapyService.getAmount() != null && therapyService.getAmount().floatValue() == 0)) {
				FacesUtil.addErrorMessage(ConstantsMsg.MSG_REQUIRE,
						new Object[] { FacesUtil.getMessage("therapy_service_amount") });
				return;
			}

			if (therapyService.getPriceUnit() == null) {
				FacesUtil.addErrorMessage(ConstantsMsg.MSG_REQUIRE,
						new Object[] { FacesUtil.getMessage("therapy_service_price") });
				return;
			}

			therapyService.setPatientTherapy(patientTherapy);
			if ((therapyService.getPriceTotal() == null || therapyService.getPriceTotal().floatValue() == 0)
					&& therapyService.getAmount().floatValue() > 0) {
				therapyService.setPriceTotal(therapyService.getAmount().floatValue() * therapyService.getPriceUnit());
			}

			therapyService = (TherapyService) evokTherapyService.merge(therapyService);
			priceTotal = null;
			priceTotal = this.getPriceTotal();
			FacesUtil.unselectTableRows("wdgServiceList");
			therapyService = new TherapyService();
			serviceId = null;
			tsModel = null;
			tsModel = this.getTsModel();
		} catch (Exception e) {
			FacesUtil.addActionListenerException(e, log);
		}
	}

	public void resetService() {
		serviceId = null;
		therapyService = new TherapyService();
	}

	@SuppressWarnings("rawtypes")
	public void deleteTherapyService() {
		try {
			evokTherapyService.delete(therapyService);
			priceTotal = null;
			priceTotal = this.getPriceTotal();
			((List) tsModel.getWrappedData()).remove(therapyService);
			therapyService = new TherapyService();
			serviceId = null;
		} catch (Exception e) {
			FacesUtil.addActionListenerException(e, log);
		}
	}

	public void countPrice() {
		if (therapyService.getPriceUnit() != null && therapyService.getAmount() != null) {
			therapyService.setPriceTotal(therapyService.getPriceUnit() * therapyService.getAmount());
		}
	}

	public void selectTherapyService(SelectEvent event) {
		therapyService = (TherapyService) event.getObject();
		EvokService service = therapyService.getService();
		serviceId = service.getId();
		unit = service.getUnit().toString();
		currency = service.getCurrency().toString();
	}

	public void uploadAtt() {
		att.setPatientTherapy(patientTherapy);

		try {
			evokTherapyService.updateTherapyAttachment(therapyAtt, att);
			FacesUtil.addInfoMessage(ConstantsMsg.INFO_SUCCESS, new Object[] { att.getAttName() });
			resetAtt();
			attmodel = null;
			attmodel = this.getAttmodel();
			FacesUtil.unselectTableRows("wdgAtt");
		} catch (Exception e) {
			FacesUtil.addActionException(e, log);
		}
	}

	public String getQyPatientName() {
		return qyPatientName;
	}

	public void setQyPatientName(String qyPatientName) {
		this.qyPatientName = qyPatientName;
	}

	public LazyDataModel<Object[]> getPatientTherapyModel() {
		if (patientTherapyModel == null) {
			patientTherapyModel = new LazyDataModel<Object[]>() {

				private static final long serialVersionUID = 1L;

				@Override
				public Object getRowKey(Object[] object) {
					return ((PatientTherapy) object[0]).getId();
				}

				@SuppressWarnings("unchecked")
				@Override
				public Object[] getRowData(String rowKey) {
					String sql = getTherapySql(null, Long.parseLong(rowKey));
					List<Object[]> list = evokTherapyService.getSqlQuery(sql).addEntity("e", PatientTherapy.class)
							.addScalar("category", Hibernate.STRING).list();
					if (list != null)
						return (Object[]) list.get(0);

					return null;
				}

				@Override
				public void setRowIndex(int rowIndex) {
					if (rowIndex == -1 || getPageSize() == 0) {
						super.setRowIndex(-1);
					} else
						super.setRowIndex(rowIndex % getPageSize());
				}

				@SuppressWarnings("unchecked")
				@Override
				public List<Object[]> load(int first, int pageSize, String sortField, SortOrder sortOrder,
						Map<String, String> filters) {

					if (domainPatient == null || FacesUtil.isKeyNull(domainPatient.getId()))
						return null;

					String sql = getTherapySql(domainPatient, null);
					String countsql = " SELECT count(e.id) FROM evk_patient_therapy e where e.domain_patient_id = "
							+ domainPatient.getId() + " and e.creator = " + FacesUtil.getUserFromSession().getId();

					Map<String, Class<?>> entities = new HashMap<String, Class<?>>();
					entities.put("e", PatientTherapy.class);

					Map<String, org.hibernate.type.Type> scalars = new HashMap<String, org.hibernate.type.Type>();
					scalars.put("category", Hibernate.STRING);

					Object[] obj = evokTherapyService.findBySql(sql, entities, scalars, countsql, first, pageSize);
					patientTherapyModel.setRowCount((Integer) obj[0]);
					return (List<Object[]>) obj[1];
				}
			};
		}
		return patientTherapyModel;
	}

	public void setPatientTherapyModel(LazyDataModel<Object[]> patientTherapyModel) {
		this.patientTherapyModel = patientTherapyModel;
	}

	public TreeNode getTherapyTree() {
		if (therapyTree == null) {
			therapyTree = evokTherapyService.getTherapyTreeForDoctor(roleId, patientTherapy);
		}
		return therapyTree;
	}

	public TreeNode[] getSelectedCategoryNodes() {
		return selectedCategoryNodes;
	}

	public void setSelectedCategoryNodes(TreeNode[] selectedCategoryNodes) {
		this.selectedCategoryNodes = selectedCategoryNodes;
	}

	@SuppressWarnings("unchecked")
	public List<PatientTherapyNode> getPnList() {
		if (pnList == null) {
			List<Node> nodelist = (List<Node>) evokTherapyService.findByNamedQuery(Node.QY_FIND_ROLE_NODES,
					new Object[] { EvokConstants.NODE_TYPE_THERAPY, roleId });
			if (nodelist == null || nodelist.isEmpty())
				return pnList;

			pnList = new ArrayList<PatientTherapyNode>();
			for (Node node : nodelist) {
				PatientTherapyNode pn = new PatientTherapyNode(node, patientTherapy);
				pnList.add(pn);
			}
		}
		return pnList;
	}

	public void setPnList(List<PatientTherapyNode> pnList) {
		this.pnList = pnList;
	}

	public DomainPatientDataModel getDomainPatientModel() {
		return domainPatientModel;
	}

	public void setDomainPatientModel(DomainPatientDataModel domainPatientModel) {
		this.domainPatientModel = domainPatientModel;
	}

	public TherapyService getTherapyService() {
		return therapyService;
	}

	public void setTherapyService(TherapyService therapyService) {
		this.therapyService = therapyService;
	}

	public Long getServiceId() {
		return serviceId;
	}

	public void setServiceId(Long serviceId) {
		this.serviceId = serviceId;
	}

	@SuppressWarnings("unchecked")
	public List<EvokService> getServiceList() {
		if (serviceList == null) {
			serviceList = (List<EvokService>) evokTherapyService.findByNamedQuery(EvokService.QY_FIND_BY_DOMAIN,
					new Object[] { this.getSessionDomain().getId() });
		}
		return serviceList;
	}

	public void setServiceList(List<EvokService> serviceList) {
		this.serviceList = serviceList;
	}

	public String getUnit() {
		return unit;
	}

	public void setUnit(String unit) {
		this.unit = unit;
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	public TherapyServiceDataModel getTsModel() {
		if (patientTherapy == null || FacesUtil.isKeyNull(patientTherapy.getId()))
			return null;

		if (tsModel == null) {
			List list = evokTherapyService.findByNamedQuery(TherapyService.QY_FIND_BY_PATIENT_THERAPY,
					new Object[] { patientTherapy.getId() });
			tsModel = new TherapyServiceDataModel(evokTherapyService, list);
		}
		return tsModel;
	}

	public void setTsModel(TherapyServiceDataModel tsModel) {
		this.tsModel = tsModel;
	}

	public String getCurrency() {
		return currency;
	}

	public void setCurrency(String currency) {
		this.currency = currency;
	}

	public String getPriceTotal() {
		if (StringUtil.isStrEmpty(priceTotal)) {
			if (!FacesUtil.isKeyNull(patientTherapy.getId())) {
				priceTotal = evokTherapyService.getPriceTotal(patientTherapy);
			}
		}
		return priceTotal;
	}

	public void setPriceTotal(String priceTotal) {
		this.priceTotal = priceTotal;
	}

	public UploadedFile getTherapyAtt() {
		return therapyAtt;
	}

	public void setTherapyAtt(UploadedFile therapyAtt) {
		this.therapyAtt = therapyAtt;
	}

	public PatientTherapyAttachment getAtt() {
		return att;
	}

	public void setAtt(PatientTherapyAttachment att) {
		this.att = att;
	}

	public TherapyAttachmentDataModel getAttmodel() {
		if (attmodel == null && patientTherapy != null && !FacesUtil.isKeyNull(patientTherapy.getId())) {
			attmodel = new TherapyAttachmentDataModel(evokTherapyService, evokTherapyService.getAttList(patientTherapy));
		}
		return attmodel;
	}

	public void resetAtt() {
		att = new PatientTherapyAttachment();
		FacesUtil.unselectTableRows("wdgAtt");
	}

	@SuppressWarnings("rawtypes")
	public void deleteAtt() {
		evokTherapyService.deleteByKey(PatientTherapyAttachment.class, att.getId());
		((List) attmodel.getWrappedData()).remove(att);
		resetAtt();
	}

	public void selectAtt(SelectEvent event) {
		att = (PatientTherapyAttachment) event.getObject();
	}

	public void setAttmodel(TherapyAttachmentDataModel attmodel) {
		this.attmodel = attmodel;
	}

	class TherapyObjectModel extends ListDataModel<Object[]> implements SelectableDataModel<Object[]> {

		@SuppressWarnings("unchecked")
		@Override
		public Object[] getRowData(String arg0) {
			if (StringUtil.isStrEmpty(arg0))
				return null;

			List<Object[]> therapies = (List<Object[]>) getWrappedData();
			if (therapies == null)
				return null;

			for (Object[] obj : therapies) {
				if (obj[0] == null)
					return null;

				if (((PatientTherapy) obj[0]).getId().toString().equals(arg0.toString()))
					return obj;
			}

			return null;
		}

		@Override
		public Object getRowKey(Object[] arg0) {
			if (arg0[0] == null)
				return null;

			return ((PatientTherapy) arg0[0]).getId();
		}
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	public void generatePdfReport(ActionEvent actionEvent) {
		if (patientTherapy == null || FacesUtil.isKeyNull(patientTherapy.getId()))
			return;

		List list = new ArrayList();
		list.add(patientTherapy);
		Connection connection = null;
		try {
			Employee emp = FacesUtil.getEmpFromSession();
			String doctorname = emp == null ? null : emp.getSurname() + " " + emp.getName();

			connection = jdbcTemplate.getDataSource().getConnection();
			List<JasperPrint> printlist = new ArrayList<JasperPrint>();
			String sql = " select c.city_name from _domain d, _city c where c.id=d.city_id and d.id = "
					+ FacesUtil.getDomainFromSession().getId();

			Map map = this.getCommonMap();
			map.put("domain_city", evokTherapyService.findSingleBySql(sql));
			map.put("patient", domainPatient.getPatient());
			map.put("patient_therapy_nodes", pnList);
			map.put("price_total", priceTotal);
			map.put("patient_therapy_id", patientTherapy.getId());
			map.put("doctor_name", doctorname);
			map.put("REPORT_CONNECTION", connection);
			JasperPrint print = ReportUtil.createJasperPrint("rp_patient_therapy", map, list);
			printlist.add(print);
			if (printlist.isEmpty())
				return;

			ReportUtil.generateReport(ReportUtil.PDF, printlist, "patientTherapy" + patientTherapy.getId());
		} catch (Exception e) {
			FacesUtil.addActionListenerException(e, log);
		} finally {
			if (connection != null) {
				try {
					connection.close();
				} catch (SQLException e) {
					log.error(e);
				}
			}
		}
	}

	public JdbcTemplate getJdbcTemplate() {
		return jdbcTemplate;
	}

	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}

	public DoctorSchedule getSchedule() {
		return schedule;
	}

	public void setSchedule(DoctorSchedule schedule) {
		this.schedule = schedule;
	}

	public int getLeftTabIndex() {
		return leftTabIndex;
	}

	public void setLeftTabIndex(int leftTabIndex) {
		this.leftTabIndex = leftTabIndex;
	}

	private void resetFlash() {
		schedule = null;
		patientTherapy = null;
		FacesContext.getCurrentInstance().getExternalContext().getFlash().put(EvokConstants.FLASH_SCHEDULE, null);
		FacesContext.getCurrentInstance().getExternalContext().getFlash()
				.put(EvokConstants.FLASH_PATIENT_THERAPY, null);
	}

	public DomainPatient getDomainPatient() {
		return domainPatient;
	}

	public void setDomainPatient(DomainPatient domainPatient) {
		this.domainPatient = domainPatient;
	}
//
//	private User sendPatientEmail(){
//		User userPatient = (User) evokTherapyService.get(User.class, domainPatient.getPatient().getUser().getId());
//		UserReference uf = userPatient.getUserReference();
//		if(StringUtil.isStrEmpty(userPatient.getEmail()))
//			return null;
//		
//		boolean sendemail = uf.getSendEmail() == null ? true : uf.getSendEmail().booleanValue();
//		if(sendemail){
//			return userPatient;
//		}
//		return null;
//	}
//	
//	private void sendReservationEmail(Integer status){
//		User patientUser = sendPatientEmail();
//		if(patientUser != null){
//			List<String> list = new ArrayList<String>();
//			list.add(patientUser.getEmail());
//			UserReference doctorReference = getSessionUser().getUserReference();
//			
//			String doctorName = doctorReference.getSurname() + " " + doctorReference.getName();
//			String patientName = patientUser.getUserReference().getSurname() + " " + patientUser.getUserReference().getName();
//			String statusString = FacesUtil.getEnumLabel("ReservationStatus", status);
//			String contentString = EvokEmailUtil.getEmailContent(EvokEmailConstants.RESERVATION_CONTENT, 
//					new Object[]{doctorName, patientName, YunDateUtil.formatDate(schedule.getTimeFrom(), "dd/MM/yyyy HH:mm")
//					, statusString},
//					getSessionDomain());
//			
//			AplikataEmail aemail = null;
//			try {
//				aemail = AplikataEmailUtil.prepareAplikataEmail(
//						FacesUtil.getEmailMessage(EvokEmailConstants.RESERVATION_SUBJECT, new Object[]{statusString}), 
//						contentString, list);
//				aemail.getEmail().send();
//			} catch (Exception e) {
//				log.error("send new reservation from doctor email failed!", e);
//				try {
//					if(aemail != null)
//						evokTherapyService.merge(aemail);
//				} catch (Exception e1) {
//					log.error("save new reservation from doctor email failed!", e1);
//				}
//			}
//		}
//	}
}
